#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

#endregion

namespace GameStateManagement
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    class GameplayScreen : GameScreen
    {

        //Sound Variables
        //public static AudioEngine audio;
        //public static WaveBank wavebank;
        //public static SoundBank soundbank;

        public static Matrix CameraMatrix, ProjectionMatrix;

        //Lighting Variables
        public static Vector3 ambientLightColor, specularColor, diffuseDirection, diffuseColor;
        public static float specularPower;


        ContentManager content;
        SpriteFont gameFont;

        Random random = new Random();

        public static ChaseCamera camera;
        Ship ship;
        Sphere sphere;
        Background background;
        Background2 background2;
        DebrisSpawnManager spawnManager;



        Utils.Timer m_kTimer = new Utils.Timer();


        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }


        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            //Sound
            //audio = new AudioEngine("Content/Sounds.xgs");
            //wavebank = new WaveBank(audio, "Content/XNAsteroids Waves.xwb");
            //soundbank = new SoundBank(audio, "Content/XNAsteroids Cues.xsb");

            //Ship


            ship = new Ship(ScreenManager.Game);
            ScreenManager.Game.Components.Add(ship);
            ship.updateWorldTransformMatrix();

            sphere = new Sphere(ScreenManager.Game);
            sphere.updateWorldTransformMatrix();
            ScreenManager.Game.Components.Add(sphere);





            background2 = new Background2(ScreenManager.Game);
            ScreenManager.Game.Components.Add(background2);

            background = new Background(ScreenManager.Game);
            ScreenManager.Game.Components.Add(background);

            spawnManager = new DebrisSpawnManager(ScreenManager.Game);
            ScreenManager.Game.Components.Add(spawnManager);



            //Camera
            camera = new ChaseCamera();

            // Set the camera offsets
            camera.DesiredPositionOffset = new Vector3(0.0f, 100.0f, 300.0f);
            camera.LookAtOffset = new Vector3(0.0f, 30.0f, 0.0f);

            // Set camera perspective
            camera.NearPlaneDistance = 0.1f;
            camera.FarPlaneDistance = 10000.0f;
            camera.AspectRatio = (float)ScreenManager.GraphicsDevice.Viewport.Width / ScreenManager.GraphicsDevice.Viewport.Height;
            updateCamera();
            camera.Reset();

            CameraMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1000.0f), Vector3.Zero, Vector3.UnitY);
            ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4.0f, 1.333f, 0.1f, 10000.0f);

            //Lighting - Ambient
            ambientLightColor = Color.Gray.ToVector3();
            ambientLightColor.Normalize();
            ambientLightColor *= 0.3f;

            //Lightin - Diffuse
            diffuseColor = Color.Silver.ToVector3();
            diffuseColor.Normalize();
            diffuseColor *= 3.0f;
            diffuseDirection = new Vector3(0.3f, -0.7f, -0.6f);

            //Lighting - Specular
            specularColor = Color.Silver.ToVector3();
            specularColor.Normalize();
            specularColor *= 0.3f;
            specularPower = 100.0f;

            gameFont = content.Load<SpriteFont>("gamefont");


            // Loading Screen
            Thread.Sleep(1000);
            ScreenManager.Game.ResetElapsedTime();




        }

        public void updateCamera()
        {
            camera.ChasePosition = ship.Position;
            camera.ChaseDirection = ship.worldTransformMatrix.Forward;
            camera.Up = ship.worldTransformMatrix.Up;

            //camera.ChasePosition = debris.Position;
            //camera.ChaseDirection = debris.worldTransformMatrix.Forward;
            //camera.Up = debris.worldTransformMatrix.Up;
        }
        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {

            spawnManager.updateRadius(sphere.getRadius());

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            float dTime = ((float)gameTime.ElapsedGameTime.Ticks / System.TimeSpan.TicksPerMillisecond / 1000.0f);

            for (int i = 0; i < ship.activeMissile.Count; i++)
            {
                Missile missile = ship.activeMissile[i];

                BoundingSphere sphereBound = sphere.WorldBounds;
                sphereBound.Radius *= 13.5f;



                if (missile.WorldBounds.Intersects(sphereBound))
                {
                    sphere.hitSphere();
                    ship.activeMissile.Remove(missile);
                    ScreenManager.Game.Components.Remove(missile);
                    break;
                }

                sphereBound = sphere.target.WorldBounds;
                sphereBound.Radius *= 11.8f;

                if (missile.WorldBounds.Intersects(sphereBound))
                {
                    sphere.hitTarget();
                    ship.activeMissile.Remove(missile);
                    ScreenManager.Game.Components.Remove(missile);
                    break;
                }

            }


            if (IsActive)
            {

                updateCamera();
                camera.Update(gameTime);



                m_kTimer.Update(gameTime);



            }


        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input, GameTime gameTime)
        {
            float dTime = ((float)gameTime.ElapsedGameTime.Ticks / System.TimeSpan.TicksPerMillisecond / 1000.0f);
            if (input == null)
                throw new ArgumentNullException("input");

            if (input.PauseGame)
            {
                // If they pressed pause, bring up the pause menu screen.
                ScreenManager.AddScreen(new PauseMenuScreen());
            }
            else
            {
                if (!ship.forceBased)
                {
                    if (input.ShipUp)
                    {
                        ship.up(gameTime);
                    }
                    if (input.ShipDown)
                    {
                        ship.down(gameTime);
                    }
                    if (input.ShipLeft)
                    {
                        ship.left(gameTime);
                    }
                    if (input.ShipRight)
                    {
                        ship.right(gameTime);
                    }
                    if (input.ShipRotCW)
                    {
                        ship.cwrot(gameTime);
                    }
                    if (input.ShipRotCCW)
                    {
                        ship.ccwrot(gameTime);
                    }
                    if (input.ShipFireLeft)
                    {
                        ship.fireLeft(gameTime, sphere.getRadius());
                    }
                    if (input.ShipFireRight)
                    {
                        ship.fireRight(gameTime, sphere.getRadius());
                    }
                }
                else
                {
                    if (input.ShipUp)
                    {
                        ship.up(gameTime);
                    }
                    else if (input.ShipDown)
                    {
                        ship.down(gameTime);
                    }
                    else
                    {
                        ship.verticalThrustOff();
                    }
                    if (input.ShipLeft)
                    {
                        ship.left(gameTime);
                    }
                    else if (input.ShipRight)
                    {
                        ship.right(gameTime);
                    }
                    else
                    {
                        ship.horizontalThrustOff();
                    }
                    if (input.ShipRotCW)
                    {
                        ship.cwrot(gameTime);
                    }
                    else if (input.ShipRotCCW)
                    {
                        ship.ccwrot(gameTime);
                    }
                    else
                    {
                        ship.rotationalThrustOff();
                    }
                    if (input.ShipFireLeft)
                    {
                        ship.fireLeft(gameTime, sphere.getRadius());
                    }
                    if (input.ShipFireRight)
                    {
                        ship.fireRight(gameTime, sphere.getRadius());
                    }

                }
                if (input.SwitchMove)
                {
                    ship.switchMove();
                }
                if (input.CamSwitch)
                {
                    ship.switchCam();
                    sphere.switchCam();
                    background.switchCam();
                    background2.switchCam();
                    spawnManager.switchCam();

                }


            }
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {

            ScreenManager.GraphicsDevice.Clear(Color.CornflowerBlue);

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();

            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0)
                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
        }


    }
}
